package cn.cj.erp.serviceimpl.system;

import cn.cj.erp.common.utils.Convert;
import cn.cj.erp.bo.system.SysUserRoleBo;
import cn.cj.erp.service.system.SysUserRoleService;
import cn.cj.erp.serviceimpl.base.ServiceImpl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.cj.erp.entity.system.SysUserRole;
import cn.cj.erp.dao.system.SysUserRoleDao;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户与角色对应关系
 *
 * @author chenjian
 */
@Slf4j
@Service
public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRole, SysUserRoleBo>
        implements SysUserRoleService {
    @Resource
    private SysUserRoleDao sysUserRoleDao;

    @Override
    public SysUserRoleDao getBaseMapper() {
        return sysUserRoleDao;
    }

    @Override
    public SysUserRole convert2Entity(SysUserRoleBo sysUserRoleBo) {
        return Convert.convert(sysUserRoleBo, SysUserRole.class);
    }

    @Override
    public SysUserRoleBo convert2Bo(SysUserRole sysUserRole) {
        return Convert.convert(sysUserRole, SysUserRoleBo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveAllRolesToUser(Long userId, List<Long> roleIds) {
        //删除用户与角色关系
        lambdaUpdate().eq(SysUserRole::getUserId, userId).remove();
        if (CollectionUtil.isEmpty(roleIds)) {
            log.info("无新增的数据，直接返回成功");
            return true;
        }
        //保存用户与角色关系
        List<SysUserRoleBo> boList = SysUserRoleBo.newList(userId, roleIds);
        boolean result = this.saveBatch(boList);
        // 当批量保存失败
        if (!result) {
            log.error("批量新增失败，打上回滚标记");
            rollback();
            return false;
        }
        return true;
    }

    @Override
    public boolean saveUsersToRole(Long roleId, List<Long> userIds) {
        if (ObjectUtil.isNull(roleId) || CollectionUtil.isEmpty(userIds)) {
            return true;
        }
        // 找到在数据库中已存在的用户角色
        List<SysUserRole> userRoleList = lambdaQuery()
                .in(SysUserRole::getUserId, userIds)
                .eq(SysUserRole::getRoleId, roleId)
                .list();
        // 并生成用户ID集合
        Set<Long> dbUserIdSet = userRoleList.stream().map(SysUserRole::getUserId)
                .collect(Collectors.toSet());
        List<SysUserRoleBo> insertList = new ArrayList<>();
        for (Long userId : userIds) {
            if (dbUserIdSet.contains(userId)) {
                // 已在数据库存在的用户ID不需要处理
                continue;
            };
            insertList.add(SysUserRoleBo.newInstance(userId, roleId));
        }
        if (CollectionUtil.isEmpty(insertList)) {
            return true;
        }
        return this.saveBatch(insertList);
    }

    @Override
    public List<Long> listRoleIdsByUserId(Long userId) {
        return getBaseMapper().listRoleIdsByUserId(userId);
    }

    @Override
    public boolean removeByRoleIds(List<Long> roleIds) {
        if (CollectionUtil.isEmpty(roleIds)) {
            log.info("没有需要删除的数据，直接返回成功");
            return true;
        }
        return lambdaUpdate().in(SysUserRole::getRoleId, roleIds).remove();
    }

    @Override
    public boolean removeByUserId(Long userId) {
        return lambdaUpdate().eq(SysUserRole::getUserId, userId).remove();
    }

    @Override
    public boolean removeUsersFromRole(Long roleId, List<Long> userIds) {
        return lambdaUpdate()
                .eq(SysUserRole::getRoleId, roleId)
                .in(SysUserRole::getUserId, userIds)
                .remove();
    }
}
